package main

import (
	"bufio"
	"fmt"
	"strings"
)

type WordCounter int // 单词计数器
type LineCounter int // 行数计数器

// 分别实现 Write 方法，以便 Fprintf 使用
func (w *WordCounter) Write(p []byte) (int, error) {
	// 写入操作时进行单词统计，返回单词数量和错误
	scanner := bufio.NewScanner(strings.NewReader(string(p)))
	// Set the split function for the scanning operation.
	scanner.Split(bufio.ScanWords)
	// Count the words.
	count := 0
	for scanner.Scan() {
		count++
	}
	if err := scanner.Err(); err != nil {
		return count, err
	}
	*w += WordCounter(count)
	return count, nil
}

func (l *LineCounter) Write(p []byte) (int, error) {
	// 写入操作时进行行数统计，返回行数和错误
	scanner := bufio.NewScanner(strings.NewReader(string(p)))
	// Set the split function for the scanning operation.
	scanner.Split(bufio.ScanLines)
	// Count the lines.
	count := 0
	for scanner.Scan() {
		count++
	}
	if err := scanner.Err(); err != nil {
		return count, err
	}
	*l += LineCounter(count)
	return count, nil
}

func main() {
	//!+main
	// 测试单词计数器
	var wc WordCounter
	line := "Hello world, hello Golang."
	wc.Write([]byte(line))
	fmt.Println(wc) // "4"

	wc = 0 // reset the counter
	fmt.Fprintf(&wc, "Wow! %s", line)
	fmt.Println(wc) // "5", 多了个单词 Wow!

	// 测试行数计数器
	var lc LineCounter
	text := `Hello world, 
hello Golang.`
	lc.Write([]byte(text))
	fmt.Println(lc) // "2"

	lc = 0 // reset the counter
	fmt.Fprintf(&lc, "Wow!\n %s", text)
	fmt.Println(lc) // "3", 多了一行 Wow!
	//!-main
}

// ScanWords() 和 ScanLines() 用法可参考：
// 	https://stackoverflow.com/questions/43450113/how-to-use-bufio-scanwords
